home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / tracker-4.13.lha / tracker / Arch / SBOS2 / audio.c next >
Encoding:
C/C++ Source or Header  |  1995-02-08  |  5.5 KB  |  222 lines

  1. /* soundblaster_audio.c */
  2.  
  3. /* modified by David Nichols for this PM MOD player */
  4.  
  5. /* MODIFIED BY Michael Fulbright (MSF) to work with os/2 device driver */
  6.  
  7. /* $Author: espie $
  8.  * $Id: audio.c,v 1.1 1995/02/01 16:43:47 espie Exp $
  9.  * $Revision: 1.1 $
  10.  * $Log: audio.c,v $
  11.  * Revision 1.1  1995/02/01  16:43:47  espie
  12.  * Initial revision
  13.  *
  14.  * Revision 1.1  1995/02/01  16:43:47  espie
  15.  * Initial revision
  16.  *
  17.  * Revision 1.1  1992/06/24  06:24:17  steve
  18.  * Initial revision
  19.  */
  20.  
  21. #define INCL_DOS
  22.  
  23. #include "defs.h"
  24. #include <os2.h>
  25. #include "sbos2_user.h"
  26. #include "extern.h"
  27. #include "song.h"
  28.  
  29. int _Stereo = TRUE;
  30.  
  31. struct sb_mixer_levels sbLevels;
  32. struct sb_mixer_params sbParams;
  33.  
  34. ID("$Id: audio.c,v 1.1 1995/02/01 16:43:47 espie Exp $");
  35.  
  36. unsigned char *buffer;        /* buffer for ready-to-play samples */
  37. LOCAL int buf_index;   /* can't call this index, conflicts with index(3) */
  38.  
  39. HFILE hAudio;      /* audio handle */
  40.  
  41. int fixparams = 0;
  42. int filterout;
  43. int filterin;
  44. int filterhi;
  45.  
  46. /* 256th of primary/secondary source for that side. */
  47. static int primary, secondary;
  48.  
  49. void restoreparams()
  50. {
  51.    ULONG parlen, datlen;
  52.  
  53.    if (fixparams)
  54.    {
  55.       parlen = 0;
  56.       datlen = sizeof(struct sb_mixer_params);
  57.       DosDevIOCtl(hAudio, DSP_CAT, MIXER_IOCTL_READ_PARAMS,
  58.              NULL, 0, &parlen, &sbParams, datlen, &datlen);
  59.       sbParams.hifreq_filter = filterhi;
  60.       sbParams.filter_output = filterout;
  61.       sbParams.filter_input = filterin;
  62.       parlen = 0;
  63.       datlen = sizeof(struct sb_mixer_params);
  64.       DosDevIOCtl(hAudio, DSP_CAT, MIXER_IOCTL_SET_PARAMS,
  65.               NULL, 0, &parlen, &sbParams, datlen, &datlen);
  66.    }
  67. }
  68.  
  69. void set_mix (int percent)
  70. {
  71.   percent *= 256;
  72.   percent /= 100;
  73.   primary = percent;
  74.   secondary = 512 - percent;
  75. }
  76.  
  77. int open_audio(int frequency, int DMAbuffersize)
  78. {
  79.   USHORT status, freq;
  80.   USHORT   flag;
  81.   ULONG  datlen, parlen, action, temp;
  82.  
  83.   /* MSF - open SBDSP for output */
  84.   status = DosOpen( "SBDSP$", &hAudio, &action, 0, FILE_NORMAL, FILE_OPEN,
  85.    OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE |
  86.    OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_NOINHERIT |
  87.    OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_FAIL_ON_ERROR, NULL );
  88.  
  89.   if (status != 0) 
  90.     end_all("Error opening audio device SBDSP$");
  91.  
  92.   /* see if we are on a SBREG or SBPRO */
  93.   status = DosOpen( "SBMIX$", &temp, &action, 0, FILE_NORMAL, FILE_OPEN,
  94.    OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE |
  95.    OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_NOINHERIT | 
  96.    OPEN_FLAGS_NO_CACHE, NULL );
  97.  
  98.   if (status !=0) _Stereo=FALSE;
  99.   else
  100.    {
  101.       fixparams = TRUE;
  102.       parlen = 0;
  103.       datlen = sizeof(struct sb_mixer_params);
  104.       DosDevIOCtl(hAudio, DSP_CAT, MIXER_IOCTL_READ_PARAMS,
  105.              NULL, 0, &parlen, &sbParams, datlen, &datlen);
  106.       filterhi = sbParams.hifreq_filter;
  107.       filterout = sbParams.filter_output;
  108.       filterin = sbParams.filter_input;
  109.       sbParams.hifreq_filter = TRUE;
  110.       sbParams.filter_output = FALSE;
  111.       sbParams.filter_input = TRUE;
  112.       parlen = 0;
  113.       datlen = sizeof(struct sb_mixer_params);
  114.       DosDevIOCtl(hAudio, DSP_CAT, MIXER_IOCTL_SET_PARAMS,
  115.                NULL, 0, &parlen, &sbParams, datlen, &datlen);
  116.       datlen=1;
  117.       parlen=0;
  118.       flag=_Stereo;
  119.       status=DosDevIOCtl(hAudio, DSP_CAT, DSP_IOCTL_STEREO,
  120.              NULL, 0, &parlen, &flag, 1, &datlen);
  121.       if (status != 0)
  122.          end_all("Error setting stereo/mono");
  123.       datlen = 1;
  124.       flag = DMAbuffersize * 1024;
  125.       DMAbuffersize = flag;
  126.       status=DosDevIOCtl(hAudio, DSP_CAT, DSP_IOCTL_BUFSIZE,
  127.                     NULL, 0, &parlen, &DMAbuffersize, datlen, &datlen);
  128.       if (status != 0)
  129.           end_all("Error setting DMA buffer size");
  130.    }
  131.  
  132.   if (_Stereo) frequency *= 2;  /* XXX Stereo takes twice the speed */
  133.  
  134.   if (frequency == 0) frequency = -1;  /* read current frequency from driver */
  135.  
  136.   /* set speed */
  137.   datlen=2;
  138.   parlen=0;
  139.   freq = (USHORT) frequency;
  140.   status=DosDevIOCtl(hAudio, DSP_CAT, DSP_IOCTL_SPEED,
  141.              NULL, 0, &parlen, &freq, 2, &datlen);
  142.   frequency=freq;
  143.   if (status!=0)
  144.       end_all("Error setting frequency");
  145.  
  146.   buffer = malloc (sizeof(SAMPLE) * frequency);    /* Stereo makes x2 */
  147.   buf_index = 0;
  148.  
  149.   if (_Stereo) return (frequency / 2);
  150.   else return (frequency);
  151. }
  152.  
  153. void output_samples (int left, int right)
  154. {
  155.   if (_Stereo)
  156.     {
  157.       buffer[buf_index++] = (((left * primary + right * secondary) / 65536) + (1 << 15)) >> 8;
  158.       buffer[buf_index++] = (((right * primary + left * secondary) / 65536) + (1 << 15)) >> 8;
  159.     }
  160.   else buffer[buf_index++] = ((left + right)/256 + (1 << 15)) >> 8;
  161. }
  162.  
  163. void discard_buffer()
  164.     {
  165.     /* not implemented */
  166.     }
  167.  
  168. void flush_buffer ()
  169. {
  170.   ULONG numread, status;
  171.  
  172.   status = DosWrite(hAudio, buffer, buf_index, &numread);
  173.    if (status != 0)
  174.    {
  175.       char buf[80];
  176.       sprintf(buf, "Error writing to audio device: %d, tried to write: %d, wrote: %d", status, buf_index, numread);
  177.       end_all(buf);
  178.    }
  179.   if (numread != buf_index)
  180.    {
  181.       char buf[80];
  182.  
  183.       sprintf(buf, "DosWrite mismatch, buf_index: %d, numread: %d", buf_index, numread);
  184.       notice(buf);
  185.    }      
  186.   buf_index = 0;
  187. }
  188.  
  189. void flush_DMA_buffers()
  190. {
  191.   ULONG status, datlen, parlen;
  192.  
  193.   /* now tell device driver to flush out internal buffers */
  194.   parlen=0;
  195.   datlen=0;
  196.   status=DosDevIOCtl(hAudio, DSP_CAT, DSP_IOCTL_FLUSH,
  197.                     NULL, 0, &parlen, NULL, 0, &datlen);
  198.    if (status != 0)
  199.    {
  200.       char buf[80];
  201.  
  202.       sprintf(buf, "Error flushing DMA buffers: %d", status);
  203.       notice(buf);
  204.    }
  205. }
  206.  
  207. void close_audio ()
  208. {
  209.    DosClose(hAudio);
  210. }
  211.  
  212. int update_frequency()
  213.     {
  214.     /* not implemented */
  215.     return 0;
  216.     }
  217.  
  218. void set_synchro(int s)
  219.     {
  220.     /* not implemented */
  221.     }
  222.